#ifndef lazy_str_hpp
#define lazy_str_hpp

#include <cstring>
#include <iostream>

class lazy_str;
class char_proxy //Маскируется под char
{
public:
	char_proxy(lazy_str & ls, size_t num) : ls_(ls), num_(num) {}
	operator char() const;
	char operator = (char ch);
private:
	lazy_str & ls_;
	size_t num_;
};

class lazy_str
{
public:
	lazy_str(const char * str) : is_copy_(true), str_ ((char *)str) {}//Плохой стиль, но иначе - оч долго
	lazy_str(lazy_str const & pr) : is_copy_(true), str_(pr.str_) {}
	~lazy_str() {if(!is_copy_) delete str_;}
	size_t size() const {return strlen(str_);}
	char const * c_str() const { return str_; }
	lazy_str & operator += (lazy_str & ls);
	char operator [] (size_t i) const {return str_[i]; }
	char_proxy operator [] (size_t i) { return char_proxy(*this, i); }

	friend bool operator < (lazy_str const & ls1, lazy_str const & ls2);
	friend bool operator == (lazy_str const & ls1, lazy_str const & ls2);
	friend std :: ostream & operator << (std :: ostream & os, lazy_str const & ls);
private:
	bool is_copy_;
	char * str_;

	void start_own_life();
	friend class char_proxy;
};

inline bool operator < (lazy_str const & ls1, lazy_str const & ls2)
{ return strcmp(ls1.str_, ls2.str_) < 0;}
inline bool operator > (lazy_str const & ls1, lazy_str const & ls2)
{ return ls2<ls1;}
inline bool operator <= (lazy_str const & ls1, lazy_str const & ls2)
{ return !(ls2<ls1); }
inline bool operator >= (lazy_str const & ls1, lazy_str const & ls2)
{ return !(ls1<ls2);}
inline bool operator == (lazy_str const & ls1, lazy_str const & ls2)
{ return strcmp(ls1.str_, ls2.str_) == 0;}
inline lazy_str operator + (lazy_str ls1, lazy_str & ls2)
{ return ls1+=ls2; }
inline std :: ostream & operator << (std :: ostream & os, lazy_str const & ls)
{ os << ls.str_; return os;}
#endif
